<?php

declare(strict_types=1);

namespace App\Controller\Api;

use Hyperf\Utils\Coroutine;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Task\Annotation\Task;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Utils\WaitGroup;
use App\Amqp\Producer\HglYcGoosChangeProducer;

class MethodTaskController extends AbstractController
{
    /**
     * @Task
     */
    public function addTask($cid,$data)
    {        
        echo "receive cid : {$cid} \r\n";
        
        $result = [];
        $arr = [$data];
        $count = count($arr);
        $wg = new WaitGroup();
        $wg->add($count);
        foreach ($arr as $key => $v ) {
            co(function () use ($wg,$key,$v,& $result) {
                $curl = curl_init();
                curl_setopt_array($curl, array(
                    CURLOPT_URL => 'http://192.168.10.211:1098/adapter/stockinforeduction',
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_ENCODING => '',
                    CURLOPT_MAXREDIRS => 10,
                    CURLOPT_TIMEOUT => 0,
                    CURLOPT_FOLLOWLOCATION => true,
                    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                    CURLOPT_CUSTOMREQUEST => 'POST',
                    CURLOPT_POSTFIELDS => json_encode($v,JSON_UNESCAPED_UNICODE),
                    CURLOPT_HTTPHEADER => array(
                        'Content-Type: application/json'
                    ),
                ));
                
                $response = curl_exec($curl);
                curl_close($curl);
                $result[$key] = $response;
                $wg->done();
            });
        }
        
        $wg->wait();
        return [
            'worker.cid' => $cid,
            // task_enable_coroutine=false 时返回 -1，反之 返回对应的协程 ID
            'task.cid' => Coroutine::id(),
            'task_response' => $result
        ];
    }
    
    public function getTask( RequestInterface $request) 
    {
        $container = ApplicationContext::getContainer();
        $task = $container->get(MethodTaskController::class);
        $json = '{"stockInfoConsumes":[{"warehouseID":219090282832986114,"supplierCommodityID":236864923429257218,"batchNo":"2021-05","number":1},{"warehouseID":219090282832986114,"supplierCommodityID":242328166931111938,"batchNo":"2021-01","number":1}]}';
        $data = json_decode($json,true);
        $result = $task->addTask(Coroutine::id(),$data);
        return $result;
    }
    

    /**
     * 下载文件
     * @param unknown $response
     */
    public function download(ResponseInterface $response) : Psr7ResponseInterface
    {
        return $response->download(BASE_PATH . '/public/file.csv', 'filename.csv');
    }
    
    /**
     * 下载文件
     * @param unknown $response
     */
    public function downloadfile()
    {
        $getSupplierOrderList = OrderSupplierModel::getSupplierOrderList();
        return $getSupplierOrderList;
        $head = [
            'names' => '商户来源订单号',
            'score' => '分数',
        ];
    
        $data = [];
        foreach ($getSupplierOrderList as $item ) {
            $data[] = [
                'names' => $item['supplier_psn'],
                'score' => $item['supplier_csn'],
            ];
        }
    
        $file_name = 'hyperf_file_export_'.(date('YmdHis')).'.csv';
        return CsvExport::export($head, $data, $file_name);
    }
    
    public function index()
    {
        $user = $this->request->input('user', 'Hyperf');
        $bid = $this->request->input('bid', '76');
        $method = $this->request->getMethod();
        //$data = GoodsMerchantListModel::where('bid',$bid)->paginate(10);
        $data = Db::table('user')->value('id');
        $data = Db::table('goods_merchant_list')->where('bid',$bid)->count();
        return [
            'method' => $method,
            'message' => "Hello {$user}.",
            'data'  => $data
            ];
    }
    
    public function getGoodsList(RequestInterface $reuqest) {
        /* $client = new \Swoole\Client(SWOOLE_SOCK_TCP);
         $client->connect('127.0.0.1', 815);
         $client->send('Hello World.');
         $ret = $client->recv(); // recv:Hello World. */
        //$data = StockmappleinfoModel::getWareHouseGoodsInfoLists();
        $data = config('server');
        return [
            'code'  => 200,
            'msg'   => '获取成功',
            'data'  => $data
        ];
    }
    
    //获取分布式唯一主键ID
    public function getSnakeId()
    {
        $container = ApplicationContext::getContainer();
        $generator = $container->get(SnowFlake::class);
        $id = $generator->getPrimaryKeyId();
        return [
            'id'        => $id,
            'idInfo'    => $generator->explainPrimaryKeyId($id)
        ];
    
        $container = ApplicationContext::getContainer();
        $generator = $container->get(IdGeneratorInterface::class);
        $time = floor(microtime(true) * 1000);
        $time = (int)$time;
        $meta = new Meta(1, 1, 0,$time);
        $id = $generator->generate();
        $meta = $generator->degenerate($id);
        return [
            'id'    => $id,
            'meta'  => $meta
        ];
    }
    
    public function getCoroutine(){
    
        co(function () {
            $channel = new \Swoole\Coroutine\Channel();
            for( $i= 0 ; $i <= 100 ; $i ++ ){
                co(function () use ($channel,$i) {
                    $res = file_get_contents('http://www.baidu.com');
                    $channel->push('data_'.$i."__".$res);
                });
            }
    
            $data = [];
            for( $i= 0 ; $i <= 100 ; $i ++ ){
                $data[] = $channel->pop();
            }
    
            return $data;
        });
    
    
    
            return 1;
    
    
    
    
    
            /* delta = 2;
             $wg = new \Hyperf\Utils\WaitGroup();
             $wg->add($delta);
             print_r($wg);die;
             // 计数器加二
             $wg->add(2);
             // 创建协程 A
             co(function () use ($wg) {
             // some code
             // 计数器减一
             $wg->done();
             });
    
             // 创建协程 B
             co(function () use ($wg) {
             // some code
             // 计数器减一
             $wg->done();
             });
    
             // 等待协程 A 和协程 B 运行完成
             $wg->wait(); */
    }
    
    /**
     * start upload file
     * @param \League\Flysystem\Filesystem $filesystem
     */
    public function upload(FilesystemFactory $factory)
    {
        $local = $factory->get('local');
        $file = $this->request->file('file');
        $getStream = $file->getStream();
        $ext = $file->getExtension();
    
        //upload file new name
        $upload_file_name = rand(10000,100000).'.'.$ext;
    
        $file_full_path = '/new/upload/'.date('Ymd').'/'.$upload_file_name;
    
        // Write Files
        //$res_local = $local->write($file_full_path,$getStream);
    
        $oss = $factory->get('oss');
        $res_oss = $oss->write($file_full_path,$getStream);
        $real_file_path = config('file.storage.oss.url').$file_full_path;
        return [
            //'res_local' => $res_local,
            'res_oss'   => $res_oss,
            'real_file_path' => $real_file_path,
        ];
    }
    
    /**
     * 获取redis
     */
    public function redis(){
        $container = ApplicationContext::getContainer();
        $redis = $container->get(Redis::class);
        return $redis->setnx('key',1);
    }
    
    /**
     * 获取分页数据
     */
    public function getOrderPageList()
    {
        return OrderSupplierModel::getPageList(56);
    }
    
    /**
     * 发布生成者消息
     * RMQ
     */
    public function publishMessage()
    {
        //上面的 RPC 调用过程是直接通过 Hyperf\Amqp\Message\DynamicRpcMessage 类来完成 Exchange 和 RoutingKey 的定义，并传递消息数据，在生产项目的设计上，我们可以对 RpcMessage 进行一层抽象，以统一 Exchange 和 RoutingKey 的定义
        //$rpcClient = ApplicationContext::getContainer()->get(RpcClient::class);
        //$data = json_decode('{"MessageType":"commodityupdate","Message":"{\"skuIDs\":[\"284728450220695682\"]}","Company":"","CreateTime":"2021-02-26T11:13:21.7067178+08:00"}',true);
        //$result = $rpcClient->call(new HglYcGoosChangeRpcMessage($data));
        //var_dump($result);
    
        $data = json_decode('{"MessageType":"commodityupdate","Message":"{\"skuIDs\":[\"284728450220695682\"]}","Company":"","CreateTime":"2021-02-26T11:13:21.7067178+08:00"}',true);
        //RPC 调用
        /*  $rpcClient = ApplicationContext::getContainer()->get(RpcClient::class);
         // 在 DynamicRpcMessage 上设置与 Consumer 一致的 Exchange 和 RoutingKey
         $result = $rpcClient->call(new HglYcGoosChangeRpcMessage($data));
         var_dump($result); */
    
        //通过 DI Container 获取 Hyperf\Amqp\Producer 实例，即可投递消息。以下实例直接使用 ApplicationContext 获取 Hyperf\Amqp\Producer 其实并不合理，DI Container 具体使用请到 依赖注入 章节中查看
        $message = new HglYcGoosChangeProducer($data);
        $producer = ApplicationContext::getContainer()->get(Producer::class);
        $result = $producer->produce($message);
        var_dump($result);
    }
}
